/******************************
 * 设置缓存（可设置有效时间）
******************************/

/** 
 * 设置缓存数据
 * 数据将会被 JSON.stringify() 转换为字符串存入
 * @param storage {Storage} 缓存的方法（localStorage还是sessionStorage）
 * @param key {String} 缓存的键值
 * @param value {String|Number|Boolean|Array|Object} 缓存的内容
 * @param expires {Number} 缓存的有效时间（单位：s）
 */
const _setStorage = (
	storage: Storage,
	key: string,
	value: string | Array<any> | Record<string, any>,
	expires?: number
) => {
	let params = { key, value, expires: expires ? expires * 1000 : expires };
	// 记录何时将值存入缓存，毫秒级
	storage.setItem(
		key,
		JSON.stringify(
			!expires ? params
				: Object.assign(params, { startTime: new Date().getTime() })
			, (_, val) =>
				val === undefined ? '__undefined__'
					: val === null ? '__null__'
						: val
		)
	);
}
const setStorage = (key: string, value: string, expires?: number) =>
	_setStorage(window.localStorage, key, value, expires);
const setSession = (key: string, value: string, expires?: number) =>
	_setStorage(window.sessionStorage, key, value, expires);


const resetStorage = (params: any) => {
	if (typeof params === 'object') {
		for (var c in params) {
			params[c] = resetStorage(params[c]);
		}
		return params
	} else if (params === '__undefined__') {
		return undefined
	} else if (params === '__null__') {
		return null
	}
	return params
}
/** 
 * 获取缓存数据
 * @param storage {Storage} 缓存的方法（localStorage还是sessionStorage）
 * @param key {String} 缓存的键值
 * @return {string|number|boolean|Array|Object} 缓存的内容
 */
const _getStorage = (storage: Storage, key: string): string | Array<any> | Record<string, any> => {
	let item: any = storage.getItem(key) || ''
	// 先将拿到的试着进行json转为对象的形式
	try {
		item = JSON.parse(item);
		resetStorage(item)
	} catch (error) {
		return null;
	}
	// 如果有startTime的值，说明设置了失效时间
	if (item && item.startTime && item.expires) {
		let date = new Date().getTime();
		// 如果大于就是过期了，如果小于或等于就还没过期
		if (date - item.startTime > item.expires) {
			storage.removeItem(key);
			return null;
		} else {
			return item.value;
		}
	} else {
		return item.value;
	}
}
const getStorage = (key: string): string | Array<any> | Record<string, any> =>
	_getStorage(window.localStorage, key)
const getSession = (key: string): string | Array<any> | Record<string, any> =>
	_getStorage(window.sessionStorage, key)

/** 
 * 删除缓存数据
 * @param storage {Storage} 缓存的方法（localStorage还是sessionStorage）
 * @param key {String} 缓存的键值
 */
const _removeStorage = (storage: Storage, key: string) =>
	storage.removeItem(key)
const removeStorage = (key: string) =>
	_removeStorage(window.localStorage, key)
const removeSession = (key: string) =>
	_removeStorage(window.sessionStorage, key)


/** 
 * 清空缓存数据
 * @param storage {Storage} 缓存的方法（localStorage还是sessionStorage）
 */
const _clearStorage = (storage: Storage) =>
	storage.clear()
const clearStorage = () =>
	_clearStorage(window.localStorage)
const clearSession = () =>
	_clearStorage(window.sessionStorage)



let api = { 
	setStorage, setSession, 
	getStorage, getSession, 
	removeStorage, removeSession, 
	clearStorage, clearSession
}
window['_'] = Object.assign(window['_'] || {}, api)
export default api